package com.aplink.generic.xmlparser;

import android.content.Context;
import android.content.res.Resources;

import com.aplink.generic.constant.ConfigParameter;
import com.aplink.generic.constant.ControlType;
import com.aplink.generic.constant.EditTextType;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.pojo.ObjectFilter;
import com.aplink.generic.pojo.controlspec.ButtonSpec;
import com.aplink.generic.pojo.controlspec.CheckBoxSpec;
import com.aplink.generic.pojo.controlspec.ControlSpec;
import com.aplink.generic.pojo.controlspec.EditTextSpec;
import com.aplink.generic.pojo.controlspec.GridViewSpec;
import com.aplink.generic.pojo.controlspec.GridViewSpec.GridViewItem;
import com.aplink.generic.pojo.controlspec.ListviewSpec;
import com.aplink.generic.pojo.controlspec.MenuSpec;
import com.aplink.generic.pojo.controlspec.PopupMenuSpec;
import com.aplink.generic.pojo.controlspec.PopupMenuSpec.PopupMenuItem;
import com.aplink.generic.pojo.controlspec.SpinnerSpec;
import com.aplink.generic.pojo.controlspec.TabHostSpec;
import com.aplink.generic.pojo.controlspec.TabHostSpec.TabItem;
import com.aplink.generic.pojo.controlspec.ViewPagerSpec;
import com.aplink.generic.pojo.controlspec.ViewPagerSpec.ViewPagerItem;
import com.aplink.generic.util.objectrule.ActionBaseRule;
import com.aplink.generic.util.objectrule.ActionCompareRule;
import com.aplink.generic.util.objectrule.ObjectBaseRule;
import com.aplink.generic.util.objectrule.ObjectLoadBaseRule;
import com.aplink.generic.util.objectrule.ObjectNotLoadBaseRule;
import com.aplink.generic.util.objectrule.TargetRule;
import com.aplink.generic.util.objectrule.TargetRuleCollection;
import com.aplink.generic.util.objectrule.ValueBaseRule;
import com.aplink.generic.util.objectrule.ValueContainRule;
import com.aplink.generic.util.objectrule.ValueEqualRule;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;

public class ControlSpecParser {

    private static ArrayList<ControlSpec> parse( Document doc, String tagName ) {
        ArrayList<ControlSpec> controlSpecList = new ArrayList<ControlSpec>();
        NodeList nList = doc.getElementsByTagName( tagName );

        if ( nList.getLength() == 0 ) {
            return null;
        }
        Node nNode = nList.item( 0 );

        if ( nNode.getNodeType() == Node.ELEMENT_NODE ) {

            Element element = (Element) nNode;
            NodeList nodes = element
                    .getElementsByTagName( ConfigParameter.CONTROL_STYLE );
            if ( nodes.getLength() == 0 ) {
                return null;
            }

            for ( int temp = 0 ; temp < nodes.getLength() ; temp++ ) {
                ControlSpec controlSpec = new ControlSpec();
                Node nControlNode = nodes.item( temp );
                String controlType = null;
                String controlId = null;
                boolean isSearch = false;
                String searchControl = null;
                String searchFields = null;
                String mappingName = null;
                String dataInputType = null;
                boolean isVisibility = true;
                int minLength = EditTextSpec.MIN_LENGTH;
                int maxLenght = EditTextSpec.MAX_LENGTH;
                String dataObject = null;
                boolean isAddBlankRow = false;
                boolean isChecked = false;
                String displayProperty = null;
                String valueProperty = null;
                String contentData = null;
                String rptrDesign = null;
                String rowItem = null;
                String selectWhere = null;
                boolean isNoBlank = false;
                boolean isReadOnly = false;
                boolean noDuplicate = false;
                String validationGroup = null;
                ObjectBaseRule objectBaseRule = null;
                String value = null;
                TargetRuleCollection targetRuleCollection = null;
                String mViewpagerHeaderStyle = null;
                int tabhostStartPageIndex = 0;
                String tabhostBackgroundColor = null;
                String tabhostDisplayStyle = null;
                boolean isViewPagerLoadByConfig = true;
                if ( nControlNode.hasAttributes() ) {
                    // find attr ctltype
                    controlType = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_TYPE );
                    controlSpec.setControlType( controlType );
                    controlId = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_ID );
                    value = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_VALUE );
                    isSearch = false;
                    if ( XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_ISSEARCH ) != null ) {
                        String val = XMLPaserUtil.getAttrValue( nControlNode,
                                ConfigParameter.CONTROL_ISSEARCH );
                        if ( val.compareToIgnoreCase( "Y" ) == 0 ) {
                            isSearch = true;
                        }
                    }
                    searchControl = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_SEARCHCTRL );
                    // find searchFields
                    searchFields = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_SEARCHFIELDS );
                    // find mapping name
                    mappingName = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_MAPPINGNAME );
                    // find inputType
                    dataInputType = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_INPUTTYPE );
                    // find Visibility Type
                    if ( XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_VISIBILITY ) != null ) {
                        String val = XMLPaserUtil.getAttrValue( nControlNode,
                                ConfigParameter.CONTROL_VISIBILITY );
                        if ( val.compareToIgnoreCase( "N" ) == 0 ) {
                            isVisibility = false;
                        }
                    }
                    // find minLength
                    minLength = EditTextSpec.MIN_LENGTH;
                    if ( XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_MINLENGTH ) != null ) {
                        String val = XMLPaserUtil.getAttrValue( nControlNode,
                                ConfigParameter.CONTROL_MINLENGTH );
                        try {
                            minLength = Integer.parseInt( val );
                        } catch ( NumberFormatException e ) {
                            minLength = EditTextSpec.MIN_LENGTH;
                        }
                    }
                    // find maxLength
                    maxLenght = EditTextSpec.MAX_LENGTH;
                    if ( XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_MAXLENGTH ) != null ) {
                        String val = XMLPaserUtil.getAttrValue( nControlNode,
                                ConfigParameter.CONTROL_MAXLENGTH );
                        try {
                            maxLenght = Integer.parseInt( val );
                        } catch ( NumberFormatException e ) {
                            maxLenght = EditTextSpec.MAX_LENGTH;
                        }
                    }
                    // find dataobj
                    dataObject = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_DATAOBJ );

                    // find addblank
                    isAddBlankRow = false;
                    if ( XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_ADDBLANKROW ) != null ) {
                        String val = XMLPaserUtil.getAttrValue( nControlNode,
                                ConfigParameter.CONTROL_ADDBLANKROW );
                        if ( val.equalsIgnoreCase( "Y" ) ) {
                            isAddBlankRow = true;
                        }
                    }
                    // find IsChecked
                    if ( XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_ISCHECKED ) != null ) {
                        String val = XMLPaserUtil.getAttrValue( nControlNode,
                                ConfigParameter.CONTROL_ISCHECKED );
                        if ( val.equalsIgnoreCase( "Y" ) ) {
                            isChecked = true;
                        }
                    }

                    // find IsChecked
                    if ( XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_OBJ_LOAD_BY_CONFIG ) != null ) {
                        String val = XMLPaserUtil.getAttrValue( nControlNode,
                                ConfigParameter.CONTROL_OBJ_LOAD_BY_CONFIG );
                        if ( val.equalsIgnoreCase( "N" ) ) {
                            isViewPagerLoadByConfig = false;
                        }
                    }

                    // find displayprop
                    displayProperty = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_DISPLAYPROP );

                    // find ValueProp
                    valueProperty = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_VALUEPROP );
                    // find ContentData
                    contentData = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_CONTENTDATA );
                    // find rptrDesign
                    rptrDesign = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_RPTRDESIGN );
                    // find rowItem
                    rowItem = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_ROWITEM );
                    // find selectWhere
                    selectWhere = XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_SELECTWHERE );

                    mViewpagerHeaderStyle = XMLPaserUtil.getAttrValue(
                            nControlNode, ConfigParameter.CONTROL_HEADER_STYLE );

                    if ( XMLPaserUtil.getAttrValue( nControlNode,
                            ConfigParameter.CONTROL_CURRENT_PAGE_INDEX ) != null ) {
                        tabhostStartPageIndex = Integer
                                .parseInt( XMLPaserUtil
                                        .getAttrValue(
                                                nControlNode,
                                                ConfigParameter.CONTROL_CURRENT_PAGE_INDEX ) );
                    }
                    tabhostBackgroundColor = XMLPaserUtil.getAttrValue(
                            nControlNode,
                            ConfigParameter.CONTROL_BACKGROUND_COLOR );

                    tabhostDisplayStyle = XMLPaserUtil.getAttrValue(
                            nControlNode, ConfigParameter.CONTROL_DISPLAY );
                }

                if ( nControlNode.getNodeType() == Node.ELEMENT_NODE ) {
                    Element elementControlNode = (Element) nControlNode;
                    // set noblank
                    NodeList nodeNonBlank = elementControlNode
                            .getElementsByTagName( ConfigParameter.CONTROL_NOBLANK );
                    if ( nodeNonBlank.getLength() != 0 ) {
                        isNoBlank = true;
                    }
                    // set ReadOnly
                    NodeList nodeReadOnly = elementControlNode
                            .getElementsByTagName( ConfigParameter.CONTROL_ISREADONLY );
                    if ( nodeReadOnly.getLength() != 0 ) {
                        isReadOnly = true;
                    }
                    // set duplicate
                    NodeList nodeDuplicate = elementControlNode
                            .getElementsByTagName( ConfigParameter.CONTROL_NODUPLICATE );
                    if ( nodeDuplicate.getLength() != 0 ) {
                        noDuplicate = true;
                    }
                    // set validationGroup
                    NodeList nodeValidationGroup = elementControlNode
                            .getElementsByTagName( ConfigParameter.CONTROL_VALIDATIONGROUP );
                    if ( nodeValidationGroup.getLength() != 0 ) {
                        validationGroup = XMLPaserUtil
                                .getNodeValue( nodeValidationGroup.item( 0 ) );
                    }
                    // find enableWhen tag
                    NodeList nodeEnableWhen = elementControlNode
                            .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN );
                    if ( nodeEnableWhen.getLength() != 0 ) {
                        // get firstNode
                        Node nEnableWhenNode = nodeEnableWhen.item( 0 );
                        objectBaseRule = setEnableCondition( nEnableWhenNode );
                    }
                    // find targets tag for ListView
                    NodeList nodeTargets = elementControlNode
                            .getElementsByTagName( ConfigParameter.CONTROL_TARGETS );
                    if ( nodeTargets.getLength() != 0 ) {
                        // get firstNode
                        Node nTargetsNode = nodeTargets.item( 0 );
                        targetRuleCollection = setTargetsCollection( nTargetsNode );
                    }
                }

                final ControlType type = controlSpec.getControlType();
                if ( type.equals( ControlType.ActionBarMenu )
                        || type.equals( ControlType.ContextMenu ) ) {
                    controlSpec = parseMenuItem( nControlNode );
                } else if ( type.equals( ControlType.GridView ) ) {
                    GridViewSpec galleryFormat = parseGalleryFormat( nControlNode );
                    galleryFormat.setContentData( contentData );
                    galleryFormat.setDataObject( dataObject );
                    galleryFormat.setRowItem( rowItem );
                    galleryFormat.setRptrdesign( rptrDesign );
                    galleryFormat.setTargetRuleCollection( targetRuleCollection );
                    controlSpec = galleryFormat;
                } else if ( type.equals( ControlType.ViewPager ) ) {
                    ViewPagerSpec pagerFormat = parseViewPagerFormat( nControlNode );
                    pagerFormat.setLoadByConfig( isViewPagerLoadByConfig );
                    pagerFormat.setHeaderStyle( mViewpagerHeaderStyle );
                    controlSpec = pagerFormat;
                } else if ( type.equals( ControlType.FragmentTabHost ) ) {
                    TabHostSpec tabhostFormat = parseTabHostFormat( nControlNode );
                    tabhostFormat.setBackgroundColor( tabhostBackgroundColor );
                    tabhostFormat.setDisplay( tabhostDisplayStyle );
                    tabhostFormat.setStartTab( tabhostStartPageIndex );
                    controlSpec = tabhostFormat;
                } else if ( type.equals( ControlType.EditText ) ) {
                    controlSpec = new EditTextSpec(
                            isNoBlank, isReadOnly, isSearch, noDuplicate,
                            EditTextType.get( dataInputType ), searchControl,
                            searchFields, minLength, maxLenght );
                } else if ( type.equals( ControlType.ListView ) ) {
                    controlSpec = new ListviewSpec( rowItem,
                            rptrDesign, contentData, targetRuleCollection,
                            selectWhere );
                } else if ( type.equals( ControlType.Spinner ) ) {
                    SpinnerSpec spinnerSpecFormat = new SpinnerSpec(
                            isAddBlankRow, displayProperty, valueProperty );
                    spinnerSpecFormat.setContentData( contentData );
                    controlSpec = spinnerSpecFormat;
                } else if ( type.equals( ControlType.Button ) ) {
                    controlSpec = new ButtonSpec(
                            targetRuleCollection );
                } else if ( type.equals( ControlType.CheckBox ) ) {
                    controlSpec = new CheckBoxSpec(
                            isChecked );
                }

                controlSpec.setControlId( controlId );
                controlSpec.setControlType( controlType );
                controlSpec.setDataObject( dataObject );
                controlSpec.setMappingName( mappingName );
                controlSpec.setValidationGroup( validationGroup );
                controlSpec.setValue( value );
                controlSpec.setVisibility( isVisibility );
                controlSpec.setObjectBaseRule( objectBaseRule );
                controlSpecList.add( controlSpec );
            }

        }
        return controlSpecList;
    }

    private static GridViewSpec parseGalleryFormat( Node nodeFormat ) {
        GridViewSpec galleryFormat = new GridViewSpec();
        Element elementFormat = (Element) nodeFormat;
        NodeList nodeListFormat = elementFormat
                .getElementsByTagName( ConfigParameter.CONTROL_LIST_FORMAT );
        nodeFormat = nodeListFormat.item( 0 );
        if ( nodeFormat.getNodeType() == Node.ELEMENT_NODE ) {
            if ( nodeFormat.hasAttributes() ) {
                String dataObject = XMLPaserUtil.getAttrValue( nodeFormat,
                        ConfigParameter.CONTROL_DATAOBJ );
                galleryFormat.setDataObject( dataObject );
            }

            elementFormat = (Element) nodeFormat;
            nodeListFormat = elementFormat
                    .getElementsByTagName( ConfigParameter.CONTROL_LIST_FORMAT_COLUMN );
            for ( int i = 0 ; i < nodeListFormat.getLength() ; i++ ) {
                Node nodeItem = nodeListFormat.item( i );
                GridViewItem galleryItem = galleryFormat.new GridViewItem();
                if ( nodeItem.hasAttributes() ) {
                    String mappingName = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_MAPPINGNAME );
                    galleryItem.setMappingName( mappingName );
                    String dataObject = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_DATAOBJ );
                    galleryItem.setDataObject( dataObject );

                    galleryFormat.add( galleryItem );
                }
            }

            nodeListFormat = elementFormat
                    .getElementsByTagName( ConfigParameter.CONTROL_FILTER );
            Node nodeFiler = nodeListFormat.item( 0 );
            if ( nodeFiler.hasAttributes() ) {
                ObjectFilter filter = new ObjectFilter();
                String mappingName = XMLPaserUtil.getAttrValue( nodeFiler,
                        ConfigParameter.CONTROL_MAPPINGNAME );
                filter.setMappingName( mappingName );
                String dataObject = XMLPaserUtil.getAttrValue( nodeFiler,
                        ConfigParameter.CONTROL_DATAOBJ );
                filter.setDataObject( dataObject );
                String defaultValue = XMLPaserUtil.getAttrValue( nodeFiler,
                        ConfigParameter.CONTROL_DEFAULT_VALUE );
                filter.setDefaultValue( defaultValue );
                galleryFormat.setFilter( filter );
            }
        }
        return galleryFormat;
    }

    private static PopupMenuSpec parsePopupMenuFormat( Node nodeFormat ) {
        Element elementFormat = (Element) nodeFormat;
        if ( elementFormat.hasChildNodes() ) {
            PopupMenuSpec popupMenuFormat = new PopupMenuSpec();
            NodeList nodeListFormat = elementFormat
                    .getElementsByTagName( ConfigParameter.CONTROL_POPUP_MENU );
            nodeFormat = nodeListFormat.item( 0 );
            if ( nodeFormat.getNodeType() == Node.ELEMENT_NODE ) {
                elementFormat = (Element) nodeFormat;
                nodeListFormat = elementFormat
                        .getElementsByTagName( ConfigParameter.CONTROL_SUB_MENU );
                for ( int i = 0 ; i < nodeListFormat.getLength() ; i++ ) {
                    Node nodeItem = nodeListFormat.item( i );
                    PopupMenuItem popupMenuItem = popupMenuFormat.new PopupMenuItem();
                    if ( nodeItem.hasAttributes() ) {
                        String title = XMLPaserUtil.getAttrValue( nodeItem,
                                ConfigParameter.CONTROL_TITLE );
                        popupMenuItem.setTitle( title );
                        String className = XMLPaserUtil.getAttrValue( nodeItem,
                                ConfigParameter.CONTROL_CLASS );
                        popupMenuItem.setClassName( className );
                        popupMenuFormat.add( popupMenuItem );
                    }
                }
            }
            return popupMenuFormat;
        }
        return null;
    }

    private static TabHostSpec parseTabHostFormat( Node nodeFormat ) {
        TabHostSpec tabHostSpecFormat = new TabHostSpec();
        Element elementFormat = (Element) nodeFormat;
        NodeList nodeListFormat = elementFormat
                .getElementsByTagName( ConfigParameter.CONTROL_TABHOST_MENU );
        nodeFormat = nodeListFormat.item( 0 );
        if ( nodeFormat.getNodeType() == Node.ELEMENT_NODE ) {
            elementFormat = (Element) nodeFormat;
            nodeListFormat = elementFormat
                    .getElementsByTagName( ConfigParameter.CONTROL_MENU );
            for ( int i = 0 ; i < nodeListFormat.getLength() ; i++ ) {
                Node nodeItem = nodeListFormat.item( i );
                TabItem tabItem = tabHostSpecFormat.new TabItem();
                if ( nodeItem.hasAttributes() ) {
                    // Get pager Class
                    String pagerItemClass = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_CLASS );
                    tabItem.setPagerItemClass( pagerItemClass );
                    // Get pager title
                    String title = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_TITLE );
                    tabItem.setTitle( title );
                    // Get pager icon
                    String icon = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_ICON );
                    tabItem.setIcon( icon );
                    // Get tag
                    String tag = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_TAG );
                    tabItem.setTag( tag );
                }
                PopupMenuSpec popupMenuFormat = parsePopupMenuFormat( nodeItem );
                tabItem.setPopupMenuFormat( popupMenuFormat );
                tabHostSpecFormat.add( tabItem );
            }
        }
        return tabHostSpecFormat;
    }

    private static ViewPagerSpec parseViewPagerFormat( Node nodeFormat ) {
        ViewPagerSpec galleryFormat = new ViewPagerSpec();
        Element elementFormat = (Element) nodeFormat;
        NodeList nodeListFormat = elementFormat
                .getElementsByTagName( ConfigParameter.CONTROL_TARGETS );
        nodeFormat = nodeListFormat.item( 0 );
        if ( nodeFormat.getNodeType() == Node.ELEMENT_NODE ) {
            if ( nodeFormat.hasAttributes() ) {
                String defaultTarget = XMLPaserUtil.getAttrValue( nodeFormat,
                        ConfigParameter.CONTROL_TARGETS_DEFAULT_TARGET );
                galleryFormat.setDefaultTarget( defaultTarget );
            }
            elementFormat = (Element) nodeFormat;
            nodeListFormat = elementFormat
                    .getElementsByTagName( ConfigParameter.CONTROL_TARGET );
            for ( int i = 0 ; i < nodeListFormat.getLength() ; i++ ) {
                Node nodeItem = nodeListFormat.item( i );
                ViewPagerItem galleryItem = galleryFormat.new ViewPagerItem();
                if ( nodeItem.hasAttributes() ) {
                    // Get pager Class
                    String pagerItemClass = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_CLASS );
                    galleryItem.setPagerItemClass( pagerItemClass );
                    // Get pager title
                    String title = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_TITLE );
                    galleryItem.setTitle( title );
                    // Get pager icon
                    String icon = XMLPaserUtil.getAttrValue( nodeItem,
                            ConfigParameter.CONTROL_ICON );
                    galleryItem.setIcon( icon );
                }
                galleryFormat.add( galleryItem );
            }
        }
        return galleryFormat;
    }

    private static MenuSpec parseMenuItem( Node menuElementNode ) {
        MenuSpec customMenu = new MenuSpec();

        Element menuNode = (Element) menuElementNode;
        NodeList listMenu = menuNode
                .getElementsByTagName( ConfigParameter.CONTROL_MENU );
        Node menuItem = listMenu.item( 0 );
        if ( menuItem.getNodeType() == Node.ELEMENT_NODE ) {
            Element elementMenuItem = (Element) menuItem;
            NodeList listMenuItem = elementMenuItem
                    .getElementsByTagName( ConfigParameter.CONTROL_SUB_MENU );
            for ( int i = 0 ; i < listMenuItem.getLength() ; i++ ) {
                Node nodeMenuItem = listMenuItem.item( i );
                if ( nodeMenuItem.hasAttributes() ) {
                    Attr attr = (Attr) nodeMenuItem.getAttributes()
                            .getNamedItem( ConfigParameter.CONTROL_ID );

                    MenuSpec.MenuItem item = customMenu.new MenuItem();
                    if ( attr != null ) {
                        String icon = attr.getNodeValue();
                        item.setId( icon );
                    }

                    // set validationGroup
                    NodeList nodeValidationGroup = ( (Element) nodeMenuItem )
                            .getElementsByTagName( ConfigParameter.CONTROL_VALIDATIONGROUP );
                    if ( nodeValidationGroup.getLength() != 0 ) {
                        String groupName = XMLPaserUtil
                                .getNodeValue( nodeValidationGroup.item( 0 ) );
                        item.setValidationgroup( groupName );
                    }
                    customMenu.add( item );
                }
            }
        }
        return customMenu;
    }

    private static ObjectBaseRule setEnableCondition( Node nEnableWhenNode ) {

        ObjectBaseRule objectBaseRule = null;

        if ( nEnableWhenNode.getNodeType() == Node.ELEMENT_NODE ) {
            Element element = (Element) nEnableWhenNode;

            // get data_rules Node
            NodeList dataRuleNodes = element
                    .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES );
            if ( dataRuleNodes.getLength() == 0 ) {
                return null;
            }
            Node nDataRuleNode = dataRuleNodes.item( 0 );

            if ( nDataRuleNode.getNodeType() == Node.ELEMENT_NODE ) {

                Element dataRuleElement = (Element) nDataRuleNode;

                // get <objloaded/> -- <objnotloaded/> -- <maxrec>

                // find objloaded tagname
                NodeList nodeObjLoaded = dataRuleElement
                        .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_OBJLOADED );
                if ( nodeObjLoaded.getLength() != 0 ) {

                    // we initiate ActionBaseRule for this Object (like
                    // <comparevalue/> or etc)
                    ActionBaseRule actionBaseRule = null;

                    NodeList nodeCompareValue = dataRuleElement
                            .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_COMPAREVALUE );
                    if ( nodeCompareValue.getLength() != 0 ) {

                        // we get NodeList rules_prop
                        NodeList nodeRuleProp = dataRuleElement
                                .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_PROP );
                        if ( nodeRuleProp.getLength() != 0 ) {
                            Node nNodeRuleProp = nodeRuleProp.item( 0 );

                            if ( nNodeRuleProp.getNodeType() == Node.ELEMENT_NODE ) {

                                Element dataRulePropElement = (Element) nNodeRuleProp;

                                // we get <prop> tag of this node
                                NodeList nodeProp = dataRulePropElement
                                        .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_PROPDETAIL );
                                if ( nodeProp.getLength() != 0 ) {

                                    Node nNodeProp = nodeProp.item( 0 );
                                    // we convert this node into element
                                    Element nodePropElement = (Element) nNodeProp;

                                    // HERE, we get whole <obj_prop> tags of
                                    // this Node
                                    NodeList objPropNodeList = nodePropElement
                                            .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_PROPDETAIL_OBJPROP );

                                    // WE CREATE ActionBaseRule for this Object
                                    // is <comparevalue/>
                                    ArrayList<ObjPropInfo> arrObjPropInfo = new ArrayList<ObjPropInfo>();

                                    for ( int temp = 0 ; temp < objPropNodeList
                                            .getLength() ; temp++ ) {
                                        Node nObjPropNode = objPropNodeList
                                                .item( temp );

                                        if ( nObjPropNode.getNodeType() == Node.ELEMENT_NODE ) {

                                            ObjPropInfo objPropInfo = new ObjPropInfo();
                                            String content;
                                            Element elementObjPropNode = (Element) nObjPropNode;

                                            // get Object_ID of this property
                                            NodeList objPropIDNodes = elementObjPropNode
                                                    .getElementsByTagName( ConfigParameter.OBJ_CLASS_ID );
                                            if ( objPropIDNodes.getLength() != 0 ) {
                                                content = XMLPaserUtil
                                                        .getNodeValue( objPropIDNodes
                                                                .item( 0 ) );
                                                objPropInfo
                                                        .setObjectMapping( content );
                                            }

                                            // get Attribute_ID of this property
                                            NodeList objPropAttributeIDNodes = elementObjPropNode
                                                    .getElementsByTagName( ConfigParameter.OBJ_PROP_ID );
                                            if ( objPropAttributeIDNodes
                                                    .getLength() != 0 ) {
                                                content = XMLPaserUtil
                                                        .getNodeValue( objPropAttributeIDNodes
                                                                .item( 0 ) );
                                                objPropInfo
                                                        .setObjectProperty( content );
                                            }

                                            // get data_type of this property
                                            NodeList objPropDataTypeNodes = elementObjPropNode
                                                    .getElementsByTagName( ConfigParameter.OBJ_PROP_DATATYPE );
                                            if ( objPropDataTypeNodes
                                                    .getLength() != 0 ) {
                                                content = XMLPaserUtil
                                                        .getNodeValue( objPropDataTypeNodes
                                                                .item( 0 ) );
                                                objPropInfo
                                                        .setDataType( content );
                                            }

                                            // get filter node of this property
                                            NodeList objPropFilterNodes = elementObjPropNode
                                                    .getElementsByTagName( ConfigParameter.OBJ_PROP_FILTER );
                                            if ( objPropFilterNodes.getLength() != 0 ) {

                                                // we get the first Filter Node
                                                Node objPropFilterNode = objPropFilterNodes
                                                        .item( 0 );

                                                // we get attribute operator and
                                                // value of this node
                                                if ( objPropFilterNode
                                                        .hasAttributes() ) {

                                                    ValueBaseRule valueBaseRule = null;
                                                    String operator = "";
                                                    String value1 = "";

                                                    // find attr operator
                                                    Attr attr = (Attr) objPropFilterNode
                                                            .getAttributes()
                                                            .getNamedItem(
                                                                    ConfigParameter.OBJ_PROP_FILTER_OPERATOR );
                                                    if ( attr != null ) {
                                                        operator = attr
                                                                .getNodeValue();
                                                    }

                                                    // find attr operator
                                                    attr = (Attr) objPropFilterNode
                                                            .getAttributes()
                                                            .getNamedItem(
                                                                    ConfigParameter.OBJ_PROP_FILTER_VALUE1 );
                                                    if ( attr != null ) {
                                                        value1 = attr
                                                                .getNodeValue();
                                                    }

                                                    // we find appropriate
                                                    // ValueBaseRule for this
                                                    // ObjPropInfo based on
                                                    // operator, value1
                                                    if ( operator
                                                            .compareToIgnoreCase( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_PROPDETAIL_FILTER_OPERATOR_EQUAL ) ==
                                                            0 ) {
                                                        valueBaseRule = new ValueEqualRule(
                                                                value1 );
                                                    } else if ( operator
                                                            .compareToIgnoreCase( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_PROPDETAIL_FILTER_OPERATOR_CONTAIN ) ==
                                                            0 ) {
                                                        valueBaseRule = new ValueContainRule(
                                                                value1 );
                                                    }

                                                    objPropInfo.valueBaseRule = valueBaseRule;
                                                }
                                            }

                                            arrObjPropInfo.add( objPropInfo );
                                        }
                                    }

                                    // set for arrObjPropInfo
                                    actionBaseRule = new ActionCompareRule(
                                            arrObjPropInfo );
                                }
                            }
                        }
                    }

                    // Eventually, it means we can create ObjectBaseRule as
                    // ObjectLoadBaseRule by an ActionBaseRule
                    objectBaseRule = new ObjectLoadBaseRule( actionBaseRule );

                }

                // find objnotloaded tagname
                NodeList nodeObjNotLoaded = dataRuleElement
                        .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_OBJNOTLOADED );
                if ( nodeObjNotLoaded.getLength() != 0 ) {
                    // it means we can create ObjectBaseRule as
                    // ObjectNotLoadBaseRule
                    objectBaseRule = new ObjectNotLoadBaseRule();
                }

                // find maxrec tagname
                NodeList nodeMaxRec = dataRuleElement
                        .getElementsByTagName( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_MAXREC );
                if ( nodeMaxRec.getLength() != 0 ) {
                    // it means we can create ObjectBaseRule as MaxRec

                }

            }
        }

        return objectBaseRule;
    }

    private static TargetRuleCollection setTargetsCollection( Node nTargetsNode ) {
        TargetRuleCollection targetRuleCollection = null;

        if ( nTargetsNode.hasAttributes() ) {

            // find attr defaultTarget
            Attr attr = (Attr) nTargetsNode.getAttributes().getNamedItem(
                    ConfigParameter.CONTROL_TARGETS_DEFAULT_TARGET );
            if ( attr != null ) {
                targetRuleCollection = new TargetRuleCollection();

                String defaultTarget = attr.getNodeValue();
                targetRuleCollection.setDefaultTarget( defaultTarget );
            }
        }

        if ( targetRuleCollection != null ) {
            if ( nTargetsNode.getNodeType() == Node.ELEMENT_NODE ) {

                Element dataTargetRuleElement = (Element) nTargetsNode;
                // and then fetch specific targets based on the value of
                // GenericObject

                // we get <rules_prop> tag of this node
                NodeList nodePropList = dataTargetRuleElement
                        .getElementsByTagName( ConfigParameter.CONTROL_TARGETS_LISTVIEW_RULES_PROPS );
                if ( nodePropList.getLength() != 0 ) {

                    ArrayList<TargetRule> targetList = new ArrayList<TargetRule>();

                    for ( int temp = 0 ; temp < nodePropList.getLength() ; temp++ ) {
                        Node targetNode = nodePropList.item( temp );

                        TargetRule targetRule = new TargetRule();
                        ActionCompareRule actionCompareRule = null;
                        // set Target for this Rule
                        if ( targetNode.hasAttributes() ) {

                            // find attr target
                            Attr attr = (Attr) targetNode.getAttributes()
                                    .getNamedItem(
                                            ConfigParameter.CONTROL_TARGET );
                            if ( attr != null ) {

                                String targetActivity = attr.getNodeValue();
                                if ( targetActivity.compareTo( "" ) == 0 ) {
                                    // we set default target activity for this
                                    // target
                                    targetRule
                                            .setTargetActivity( targetRuleCollection
                                                    .getDefaultTarget() );
                                } else {
                                    targetRule
                                            .setTargetActivity( targetActivity );
                                }
                            }
                        }

                        // we fetch obj_prop for this target
                        if ( targetNode.getNodeType() == Node.ELEMENT_NODE ) {
                            // we set TargetRule by ObjPropInfo, we create list
                            // of ObjPropInfo
                            Element targetNodeElement = (Element) targetNode;

                            // we get <prop> tag of this node
                            NodeList nodeProp = targetNodeElement
                                    .getElementsByTagName( ConfigParameter.CONTROL_TARGETS_LISTVIEW_RULES_PROPS_PROP );
                            if ( nodeProp.getLength() != 0 ) {

                                Node nNodeProp = nodeProp.item( 0 );
                                // we convert this node into element
                                Element nodePropElement = (Element) nNodeProp;

                                // HERE, we get whole <obj_prop> tags of this
                                // Node
                                NodeList objPropNodeList = nodePropElement
                                        .getElementsByTagName( ConfigParameter.CONTROL_TARGETS_LISTVIEW_RULES_PROPS_PROP_OBJPROP );

                                ArrayList<ObjPropInfo> arrObjPropInfo = new ArrayList<ObjPropInfo>();

                                for ( int objpropIndex = 0 ; objpropIndex < objPropNodeList
                                        .getLength() ; objpropIndex++ ) {
                                    Node nObjPropNode = objPropNodeList
                                            .item( objpropIndex );

                                    if ( nObjPropNode.getNodeType() == Node.ELEMENT_NODE ) {

                                        ObjPropInfo objPropInfo = new ObjPropInfo();
                                        String content;
                                        Element elementObjPropNode = (Element) nObjPropNode;

                                        // get Object_ID of this property
                                        NodeList objPropIDNodes = elementObjPropNode
                                                .getElementsByTagName( ConfigParameter.OBJ_CLASS_ID );
                                        if ( objPropIDNodes.getLength() != 0 ) {
                                            content = XMLPaserUtil
                                                    .getNodeValue( objPropIDNodes
                                                            .item( 0 ) );
                                            objPropInfo
                                                    .setObjectMapping( content );
                                        }

                                        // get Attribute_ID of this property
                                        NodeList objPropAttributeIDNodes = elementObjPropNode
                                                .getElementsByTagName( ConfigParameter.OBJ_PROP_ID );
                                        if ( objPropAttributeIDNodes.getLength() != 0 ) {
                                            content = XMLPaserUtil
                                                    .getNodeValue( objPropAttributeIDNodes
                                                            .item( 0 ) );
                                            objPropInfo
                                                    .setObjectProperty( content );
                                        }

                                        // get data_type of this property
                                        NodeList objPropDataTypeNodes = elementObjPropNode
                                                .getElementsByTagName( ConfigParameter.OBJ_PROP_DATATYPE );
                                        if ( objPropDataTypeNodes.getLength() != 0 ) {
                                            content = XMLPaserUtil
                                                    .getNodeValue( objPropDataTypeNodes
                                                            .item( 0 ) );
                                            objPropInfo.setDataType( content );
                                        }

                                        // get filter node of this property
                                        NodeList objPropFilterNodes = elementObjPropNode
                                                .getElementsByTagName( ConfigParameter.OBJ_PROP_FILTER );
                                        if ( objPropFilterNodes.getLength() != 0 ) {

                                            // we get the first Filter Node
                                            Node objPropFilterNode = objPropFilterNodes
                                                    .item( 0 );

                                            // we get attribute operator and
                                            // value of this node
                                            if ( objPropFilterNode
                                                    .hasAttributes() ) {

                                                ValueBaseRule valueBaseRule = null;
                                                String operator = "";
                                                String value1 = "";

                                                // find attr operator
                                                Attr attr = (Attr) objPropFilterNode
                                                        .getAttributes()
                                                        .getNamedItem(
                                                                ConfigParameter.OBJ_PROP_FILTER_OPERATOR );
                                                if ( attr != null ) {
                                                    operator = attr
                                                            .getNodeValue();
                                                }

                                                // find attr operator
                                                attr = (Attr) objPropFilterNode
                                                        .getAttributes()
                                                        .getNamedItem(
                                                                ConfigParameter.OBJ_PROP_FILTER_VALUE1 );
                                                if ( attr != null ) {
                                                    value1 = attr
                                                            .getNodeValue();
                                                }

                                                // we find appropriate
                                                // ValueBaseRule for this
                                                // ObjPropInfo based on
                                                // operator, value1
                                                if ( operator
                                                        .compareToIgnoreCase( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_PROPDETAIL_FILTER_OPERATOR_EQUAL ) ==
                                                        0 ) {
                                                    valueBaseRule = new ValueEqualRule(
                                                            value1 );
                                                } else if ( operator
                                                        .compareToIgnoreCase( ConfigParameter.CONTROL_ENABLEWHEN_DATA_RULES_PROPDETAIL_FILTER_OPERATOR_CONTAIN ) ==
                                                        0 ) {
                                                    valueBaseRule = new ValueContainRule(
                                                            value1 );
                                                }

                                                objPropInfo.valueBaseRule = valueBaseRule;
                                            }
                                        }

                                        arrObjPropInfo.add( objPropInfo );
                                    }

                                }
                                // we set arrObjPropInfo for this TargetRule
                                actionCompareRule = new ActionCompareRule(
                                        arrObjPropInfo );
                            }

                            // it must be ActioNCompareRule
                            targetRule.setActionBaseRule( actionCompareRule );
                        }

                        // add currentTarget into TargetList
                        targetList.add( targetRule );
                    }

                    // set TargetList for current Rule Collection
                    targetRuleCollection.setArrTargetRules( targetList );
                }
            }
        }

        return targetRuleCollection;
    }

    public static ArrayList<ControlSpec> parserIntoControls(
            Context paramContext, int xmlfileId, String tagname ) {
        try {
            Document doc = XMLPaserUtil.openDocumentFrom( paramContext,
                    xmlfileId );
            return parse( doc, tagname );
        } catch ( ParserConfigurationException e ) {
            e.printStackTrace();
        } catch ( SAXException e ) {
            e.printStackTrace();
        } catch ( IOException e ) {
            e.printStackTrace();
        } catch ( Resources.NotFoundException e ) {
            e.printStackTrace();
        }
        return new ArrayList<ControlSpec>();
    }

    public static ArrayList<ControlSpec> parserIntoControls(
            Context paramContext, String xmlfilename, String tagname ) {
        Document doc;
        try {
            doc = XMLPaserUtil.openDocumentFrom( paramContext, xmlfilename );
            return parse( doc, tagname );
        } catch ( ParserConfigurationException e ) {
            e.printStackTrace();
        } catch ( SAXException e ) {
            e.printStackTrace();
        } catch ( IOException e ) {
            e.printStackTrace();
        }
        return null;
    }

}
